package com.dhcc.bpm.alarm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dhcc.bpm.alarm.entity.AlarmNotice;
import com.dhcc.bpm.alarm.entity.AlarmObject;
import com.dhcc.bpm.alarm.entity.AlarmStrategy;
import com.dhcc.bpm.alarm.entity.statistic.AlarmStatistic;
import com.dhcc.bpm.alarm.mapper.AlarmNoticeInfoMapper;
import com.dhcc.bpm.alarm.mapper.AlarmStatisticMapper;
import com.dhcc.bpm.alarm.service.IAlarmObjectService;
import com.dhcc.bpm.alarm.service.IAlarmStatisticService;
import com.dhcc.bpm.alarm.service.IAlarmStrategyInfoService;
import com.dhcc.bpm.alarm.vo.AlarmStatisticVO;
import com.dhcc.bpm.alarm.vo.statistics.AlarmJoinClassVO;
import com.dhcc.bpm.alarm.vo.statistics.AlarmStrategyTimeVO;
import com.dhcc.bpm.alarm.vo.statistics.StatisticsStrategyVO;
import com.dhcc.bpm.modules.api.service.ISysService;
import com.dhcc.bpm.modules.api.vo.SysVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Description 告警统计服务类
 * @author caoyanlong
 * @date 20220223
 */
@Slf4j
@Service
public class AlarmStatisticServiceImpl implements IAlarmStatisticService{
	
	@Autowired
	private AlarmStatisticMapper alarmStatisticMapper;
	
	@Autowired
	private AlarmNoticeInfoMapper alarmNoticeInfoMapper;
	
	@Autowired
	private IAlarmObjectService alarmObjectService;
	
	@Autowired
	private IAlarmStrategyInfoService alarmStrategyInfoService;
	
	@Autowired
	private ISysService sysService;
	
	/**
	 * @description 接入渠道,  策略数量,  预警数量 
	 * @param alarmRecord
	 * @return
	 */
	@Override
	public List<AlarmStatisticVO> classNum(AlarmStatistic request) {
		List<AlarmStatisticVO> resultList = alarmStatisticMapper.classNumber(request); 
		return resultList;
	}
	
	/**
	 * @description 告警数量TOP5
	 * @param alarmRecord
	 * @return
	 */
	@Override
	public List<AlarmStatisticVO> alarmNumber(AlarmStatistic request) {
		
		setDateValue(request);
		List<AlarmStatisticVO> resultList = alarmStatisticMapper.alarmNumber(request);
		if(resultList.size() <= 0) {
			
			QueryWrapper<AlarmNotice> queryWrapper = new QueryWrapper<AlarmNotice>();
			queryWrapper.last("where ROWNUM <= 5");
			
			List<AlarmNotice> noticeList = alarmNoticeInfoMapper.selectList(queryWrapper);
			
			noticeList.forEach(alarmNotice ->{
				resultList.add(new AlarmStatisticVO(alarmNotice.getNoticeName(),"0"));
			});
		}
		return resultList;
	}
	
	/**
	 * @description 告警通道分布
	 * @param alarmRecord
	 * @return
	 */
	@Override
	public List<AlarmStatisticVO> alarmNoticeMethod(AlarmStatistic request) {
		setDateValue(request);
		List<AlarmStatisticVO> resultList = alarmStatisticMapper.alarmNoticeMethod(request);
		
		if(resultList.size() ==0) {
			String[] methods = new String[]{"短信","微信","邮箱","API","H5"};
			
			for(String method : methods) {
				AlarmStatisticVO vo = new AlarmStatisticVO ();
				vo.setType(method);
				vo.setValue("0");
				resultList.add(vo);
			}
		}
		return resultList;
	}
	
	/**
	 * @description 紧急告警数量
	 */
	@Override
	public List<AlarmStatisticVO> alarmUrgentNum(AlarmStatistic request) {
		List<AlarmStatisticVO> resultList = alarmStatisticMapper.alarmUrgentNum(request);
		return resultList;
	}
	
	/**
	 * @description 系统维度预警
	 */
	@Override
	public List<AlarmStatisticVO> alarmSystem(AlarmStatistic request) {
		setDateValue(request);
		List<AlarmStatisticVO> resultList = alarmStatisticMapper.alarmSystem(request);
		if(resultList.size() == 0) {
			
			Query query = new Query();
			query.setCurrent(1);
			query.setSize(5);
			query.setDescs("CREATE_TIME");
			IPage<SysVO> page = sysService.selectSysPage(Condition.getPage(query), new SysVO());
			if(page.getTotal()>0) {
				List<SysVO> list = page.getRecords();
				
				list.forEach(sys ->{
					resultList.add(new AlarmStatisticVO(sys.getSysName(), "0"));
				});
			}
		}
		return resultList;
	}

	@Override
	public List<AlarmStatisticVO> alarmObj(AlarmStatistic request) {
		
		setDateValue(request);
		List<AlarmStatisticVO> resultList = alarmStatisticMapper.alarmObj(request);
		if(resultList.size() == 0) {
			Query query = new Query();
			query.setCurrent(1);
			query.setSize(5);
			query.setDescs("ID");
			IPage<AlarmObject> page = alarmObjectService.page(Condition.getPage(query), Condition.getQueryWrapper(new AlarmObject()));
			if(page.getTotal() > 0) {
				List<AlarmObject> list = page.getRecords();
				list.forEach(obj ->{
					resultList.add(new AlarmStatisticVO(obj.getObjectname(), "0"));
				});
			}
		}
		
		return resultList;
		
	}

	/**
	 * @description 告警数量分布
	 */
	@Override
	public List<AlarmStatisticVO> alarmNumGroup(AlarmStatistic request) {
		
		setDateValue(request);
		List<AlarmStatisticVO> resultList = alarmStatisticMapper.alarmNumGroup(request);
		if(resultList.size()==0) {
//			QueryWrapper<AlarmNotice> queryWrapper = new QueryWrapper<AlarmNotice>();
//			queryWrapper.last("where ROWNUM <= 5");
//			List<AlarmNotice> noticeList = alarmNoticeInfoMapper.selectList(queryWrapper);
//			
//			noticeList.forEach(alarmNotice ->{
//				resultList.add(new AlarmStatisticVO(alarmNotice.getNoticeName(),"0"));
//			});
			
			Query query = new Query();
			query.setCurrent(1);
			query.setSize(5);
			query.setDescs("ID");
			IPage<AlarmStrategy> page = alarmStrategyInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(new AlarmStrategy()));
			if(page.getTotal() > 0) {
				List<AlarmStrategy> list = page.getRecords();
				list.forEach(obj ->{
					resultList.add(new AlarmStatisticVO(obj.getStrategyName(), "0"));
				});
			}
		}
		
		
		return resultList;
	}
	
	/**
	 * @description 告警数量分布
	 */
	@Override
	public List<AlarmStatisticVO> alarmStsNum(AlarmStatistic request) {
		setDateValue(request);
		List<AlarmStatisticVO> resultList = alarmStatisticMapper.alarmStsNum(request);
		
		return resultList;
	}
	
	/**
	 * @Description 系统策略数量
	 */
	@Override
	public List<AlarmStatisticVO> alarmStrategy(AlarmStatistic request) {
		
		setDateValue(request);
		
		List<AlarmStatisticVO> resultList = alarmStatisticMapper.alarmStrategy(request);
		if(resultList.size() == 0) {
			Query query = new Query();
			query.setCurrent(1);
			query.setSize(5);
			query.setDescs("CREATE_TIME");
			IPage<SysVO> page = sysService.selectSysPage(Condition.getPage(query), new SysVO());
			if(page.getTotal()>0) {
				List<SysVO> list = page.getRecords();
				
				list.forEach(sys ->{
					resultList.add(new AlarmStatisticVO(sys.getSysName(), "0"));
				});
			}
		}
		
		return resultList;
	}
	
	private void setDateValue(AlarmStatistic alarmStatistic) {
		LocalDate today = LocalDate.now();
		DateTimeFormatter datatimeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
		String todayStart = LocalDateTime.of(today, LocalTime.MIN).format(datatimeFormat);//当天零点
		String todayEnd = LocalDateTime.of(today, LocalTime.MAX).format(datatimeFormat);//当天零点
		
		alarmStatistic.setStartTime(todayStart);
		alarmStatistic.setEndTime(todayEnd);
	}
	
	/**
	 * 策略统计展示
	 */
	@Override
	public List<StatisticsStrategyVO> alarmStrategyByCode(AlarmStatistic alarmStatistic) {
		
		//策略日预警次数
		int totalNum = alarmStatisticMapper.alarmStatisticByCode(alarmStatistic);
		
		LocalDate today = LocalDate.now();
		DateTimeFormatter datatimeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
		String todayStart = LocalDateTime.of(today, LocalTime.MIN).format(datatimeFormat);//当天零点
		String todayEnd = LocalDateTime.of(today, LocalTime.MAX).format(datatimeFormat);//当天零点
		
		//策略预警次数
		alarmStatistic.setStartTime(todayStart);
		alarmStatistic.setEndTime(todayEnd);
		int dayNum = alarmStatisticMapper.alarmStatisticByCode(alarmStatistic);
		
		// 策略关联-系统数量 
		int sysNum = alarmStatisticMapper.alarmStatisticJoinNum(alarmStatistic);  
		
		// 策略关联通道数量
		int chnlNum = alarmStatisticMapper.alarmStatisticMethodNum(alarmStatistic); 
		
		List<StatisticsStrategyVO> resultList = new ArrayList<StatisticsStrategyVO>();
		resultList.add(new StatisticsStrategyVO("策略预警次数", totalNum, "笔"));
		resultList.add(new StatisticsStrategyVO("策略日预警次数", dayNum, "笔"));
		resultList.add(new StatisticsStrategyVO("策略关联-系统数量", sysNum, "笔"));
		resultList.add(new StatisticsStrategyVO("策略关联-通道数量", chnlNum, "笔"));
		
		return resultList;
	}
	
	/**
	 * 告警统计图
	 * 传入timeType:hh24-近24小时、dd7-近7日、dd30天、yy1-当年,strategyCode
	 */
	@Override
	public List<AlarmStrategyTimeVO> alarmStrategyTime(AlarmStatistic alarmStatistic) {
		
		String timeType = alarmStatistic.getTimeType();
		
		// 设置开始时间和结束时间
		setTimeByType(alarmStatistic);
		
		// 获取时间轴集合
		List<String> timeList = intervalTime(alarmStatistic.getStartTime(), alarmStatistic.getEndTime(),  timeType);
		
		List<AlarmStrategyTimeVO> resultList = new ArrayList<AlarmStrategyTimeVO>();
		
		if(StringUtils.isNotBlank(alarmStatistic.getStrategyCode())) {
			if("1".equals(timeType)) {
				// 按每十分钟分组查询
				resultList = alarmStatisticMapper.alarmStrategyTimeMinute(alarmStatistic);
			}else if("2".equals(timeType)) {
				// 按小时查询
				resultList = alarmStatisticMapper.alarmStrategyTimeHours(alarmStatistic);
			}else if("3".equals(timeType) || "4".equals(timeType)) {
				// 按天查询 
				resultList = alarmStatisticMapper.alarmStrategyTimeDays(alarmStatistic);
			}
		}else if(StringUtils.isNotBlank(alarmStatistic.getSystemNo())){
			if("1".equals(timeType)) {
				// 按每十分钟分组查询
				resultList = alarmStatisticMapper.alarmSystemTimeMinute(alarmStatistic);
			}else if("2".equals(timeType)) {
				// 按小时查询
				resultList = alarmStatisticMapper.alarmSystemTimeHours(alarmStatistic);
			}else if("3".equals(timeType) || "4".equals(timeType)) {
				// 按天查询 
				resultList = alarmStatisticMapper.alarmSystemTimeDays(alarmStatistic);
			}
		}
		
		for(String time : timeList) {
			final String[] metods = {"短信", "微信", "邮箱", "API", "H5"};
			for(String method : metods) {
				boolean exist = resultList.stream().anyMatch(timeVO -> timeVO.getTime().equals(time) && method.equals(timeVO.getLabel()));
				if(!exist) {
					resultList.add(new AlarmStrategyTimeVO(time, method, "0"));
				}
			}
		}
		
		resultList = resultList.stream().sorted(Comparator.comparing(AlarmStrategyTimeVO::getTime)).collect(Collectors.toList());
		
		if("1".equals(timeType) || "2".equals(timeType)) { // 24小时和7天内的格式化时间
			
			for(AlarmStrategyTimeVO vo: resultList) { 
				// 不同的时间类型，展示时间不一样。
				if("1".equals(timeType)) {
					String timeHHmm = vo.getTime().substring(8)+"0";
					StringBuffer sb = new StringBuffer();
					sb.append(timeHHmm);
					vo.setTime(sb.insert(2, ":").toString());  // HH
				}else if("2".equals(timeType)) {
					String timeHHmm = vo.getTime().substring(4);
					StringBuffer sb = new StringBuffer();
					sb.append(timeHHmm);
					vo.setTime(sb.insert(4, " ").insert(2, "-").append(":00").toString());  // MMdd HH:00
				}
			}
		}
		
		return resultList;
	}
	
	private void setTimeByType(AlarmStatistic alarmStatistic) {
		
		String timeType = alarmStatistic.getTimeType();
		
		Date nowDate = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(nowDate);
		
		if("1".equals(timeType)) {
			calendar.add(Calendar.HOUR, -24);
			alarmStatistic.setStartTime((Long.parseLong(DateFormatUtils.format(calendar.getTime(), "yyyyMMddHHmmss"))/1000)+"000");
			alarmStatistic.setEndTime((Long.parseLong(DateFormatUtils.format(nowDate, "yyyyMMddHHmmss"))/1000)+"959");
		}else if("2".equals(timeType)) {
			calendar.add(Calendar.DAY_OF_MONTH, -7);
			
			alarmStatistic.setStartTime(DateFormatUtils.format(calendar.getTime(), "yyyyMMddHH0000"));
			alarmStatistic.setEndTime(DateFormatUtils.format(nowDate, "yyyyMMddHH5959"));
			
		}else if("3".equals(timeType)) {
			//calendar.add(Calendar.MONTH, -1); // 一个月
			calendar.add(Calendar.DAY_OF_MONTH, -30); // 三十天
			
			alarmStatistic.setStartTime(DateFormatUtils.format(calendar.getTime(), "yyyyMMdd"));
			alarmStatistic.setEndTime(DateFormatUtils.format(nowDate, "yyyyMMdd"));
			
		}else if("4".equals(timeType)) {
			calendar.add(Calendar.YEAR, -1);
			
			alarmStatistic.setStartTime(DateFormatUtils.format(calendar.getTime(), "yyyyMMdd"));
			alarmStatistic.setEndTime(DateFormatUtils.format(nowDate, "yyyyMMdd"));
		}
		
	}
	
	
	private static List<String> intervalTime(String startTime, String endTime,String timeType) {
		
		
		
		try {
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
			if("3".equals(timeType) || "4".equals(timeType)) {
				dateFormat = new SimpleDateFormat("yyyyMMdd");
			}
			Date startTm = dateFormat.parse(startTime);
			Date endTm = dateFormat.parse(endTime);
			
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(startTm);
			calendar.set(Calendar.MILLISECOND, 0);
			
			List<String> timeList = new ArrayList<String>();
			
			while(calendar.getTime().compareTo(endTm) <= 0 ) {
				
				String time="";
				if("1".equals(timeType)) { 
					// 按每十分钟分组
					time = (Long.parseLong(DateFormatUtils.format(calendar.getTime(), "yyyyMMddHHmm"))/10) +"";
					calendar.add(Calendar.MINUTE, 10);
				}else if("2".equals(timeType)) { 
					// 按小时分组
					time = DateFormatUtils.format(calendar.getTime(), "yyyyMMddHH");
					calendar.add(Calendar.HOUR_OF_DAY, 1);
				}else if("3".equals(timeType) || "4".equals(timeType)) {
					// 按天分组 
					time = DateFormatUtils.format(calendar.getTime(), "yyyyMMdd");
					calendar.add(Calendar.DAY_OF_MONTH, 1); 
				}
				
				timeList.add(time);
			}
			
			return timeList;
			
		} catch (ParseException e) {
			log.info("时间转换异常：{}", e);
		}
		return null;
		
	}
	public static void main(String[] args) {
		
		List<String> timeList = intervalTime("20220328145000", "20220329145959","2");
		
		timeList.forEach(time -> { 
			System.out.println(time); 
		});
		
	}
	
	/**
     * @Description 关联系统列表
     * @Param 
     */
	@Override
	public IPage<AlarmJoinClassVO> alarmJoinStrategy(IPage<AlarmJoinClassVO> page, AlarmStatistic alarmStatistic) {
		return page.setRecords(alarmStatisticMapper.alarmJoinStrategy(page, alarmStatistic));
	}
	
	/**
     * @Description 关联策略列表
     * @Param 
     */
	@Override
	public IPage<AlarmJoinClassVO>  alarmJoinMethod(IPage<AlarmJoinClassVO> page, AlarmStatistic alarmStatistic) {
		return page.setRecords(alarmStatisticMapper.alarmJoinMethod(page, alarmStatistic));
	}

	@Override
	public int getAlarmCount(AlarmStatistic alarmStatistic) {
		return alarmStatisticMapper.selectAlarmCount(alarmStatistic);
	}

	

	


	

}
